home *** CD-ROM | disk | FTP | other *** search
/ InfoMagic Internet Tools 1993 July / Internet Tools.iso / RockRidge / mail / mmdf / mmdf-IIb.43 / src / local / qu2lo_send.c < prev    next >
Encoding:
C/C++ Source or Header  |  1990-02-28  |  6.4 KB  |  265 lines

  1. /*
  2.  *     MULTI-CHANNEL MEMO DISTRIBUTION FACILITY  (MMDF)
  3.  *
  4.  *
  5.  *     Copyright (C) 1979,1980,1981  University of Delaware
  6.  *
  7.  *     Department of Electrical Engineering
  8.  *     University of Delaware
  9.  *     Newark, Delaware  19711
  10.  *
  11.  *     Phone:  (302) 738-1163
  12.  *
  13.  *
  14.  *     This program module was developed as part of the University
  15.  *     of Delaware's Multi-Channel Memo Distribution Facility (MMDF).
  16.  *
  17.  *     Acquisition, use, and distribution of this module and its listings
  18.  *     are subject restricted to the terms of a license agreement.
  19.  *     Documents describing systems using this module must cite its source.
  20.  *
  21.  *     The above statements must be retained with all copies of this
  22.  *     program and may not be removed without the consent of the
  23.  *     University of Delaware.
  24.  *
  25.  *
  26.  *     version  -1    David H. Crocker    March   1979
  27.  *     version   0    David H. Crocker    April   1980
  28.  *     version  v7    David H. Crocker    May     1981
  29.  *     version   1    David H. Crocker    October 1981
  30.  *
  31.  */
  32. /*                  SEND FROM DELIVER TO LOCAL MACHINE
  33.  *
  34.  *  Jul 81 Dave Crocker     change to have a child handle actual delivery,
  35.  *          + BRL crew      setuid'ing to recipient.
  36.  *  Aug 81 Steve Bellovin   mb_unlock() added to x2y_each
  37.  *  Apr 84 Doug Kingston    Major rewrite.
  38.  *  Aug 84 Julian Onions    Extended the delivery file syntax quite a bit
  39.  *  Feb 85 Julian Onions    Reworked to parse only if really really necessary
  40.  */
  41.  
  42. #include "util.h"
  43. #include "mmdf.h"
  44. #include "phs.h"
  45. #include "ap.h"
  46. #include "ch.h"
  47. #include <pwd.h>
  48. #include <sys/stat.h>
  49. #include <signal.h>
  50. #include <sgtty.h>
  51. #include "adr_queue.h"
  52.  
  53. char    lo_info[2 * LINESIZE],
  54.     lo_sender[2 * LINESIZE],
  55.     lo_adr[2 * LINESIZE],
  56.     lo_replyto[2 * LINESIZE],
  57.     lo_size[16],
  58.     *lo_parm;
  59.  
  60. struct passwd *lo_pw;
  61.  
  62. extern Chan     *chanptr;
  63. extern LLog     *logptr;
  64.  
  65. extern int      errno;
  66.  
  67. extern char     *qu_msgfile;          /* name of file containing msg text   */
  68. extern long     qu_msglen;
  69.  
  70. extern char *index();
  71. extern struct passwd *getpwmid();
  72.  
  73. LOCFUN qu2lo_each(), lo_verify(), lo_master();
  74.  
  75. LOCVAR struct rp_construct
  76. rp_aend  =
  77. {
  78.     RP_OK, 'l', 'o', 'c', ' ', 'e', 'n', 'd', ' ', 'o', 'f', ' ', 'a',
  79.     'd', 'd', 'r', ' ', 'l', 'i', 's', 't', '\0'
  80. },
  81. rp_hend  =
  82. {
  83.     RP_NOOP, 'e', 'n', 'd', ' ', 'o', 'f', ' ', 'h', 'o', 's', 't', ' ',
  84.     'i', 'g', 'n', 'o', 'r', 'e', 'd', '\0'
  85. };
  86.  
  87. /* */
  88.  
  89. qu2lo_send ()                       /* overall mngmt for batch of msgs    */
  90. {
  91.     short     result;
  92.  
  93. #ifdef DEBUG
  94.     ll_log (logptr, LLOGBTR, "qu2lo_send ()");
  95. #endif
  96.  
  97.     if (rp_isbad (result = qu_pkinit ()))
  98.         return (result);
  99.  
  100.     /* While there are messages to process... */
  101.     for(;;){
  102.         result = qu_rinit (lo_info, lo_sender, chanptr -> ch_apout);
  103.         if(rp_gval(result) == RP_NS){
  104.             qu_rend();
  105.             continue;
  106.         }
  107.         else if(rp_gval(result) != RP_OK)
  108.             break;
  109.         phs_note (chanptr, PHS_WRSTRT);
  110.  
  111.         sprintf (lo_size, "%ld", qu_msglen);
  112.         result = qu2lo_each ();
  113.         qu_rend();
  114.         if (rp_isbad (result))
  115.             return (result);
  116.     }
  117.  
  118.     if (rp_gval (result) != RP_DONE)
  119.     {
  120.         ll_log (logptr, LLOGTMP, "not DONE (%s)", rp_valstr (result));
  121.         return (RP_RPLY);         /* catch protocol errors      */
  122.     }
  123.  
  124.     qu_pkend ();                  /* done getting messages          */
  125.     phs_note (chanptr, PHS_WREND);
  126.  
  127.     return (result);
  128. }
  129. /* */
  130.  
  131. LOCFUN
  132. qu2lo_each ()               /* send copy of text per address      */
  133. {
  134.     RP_Buf  replyval;
  135.     short   result;
  136.     char    host[LINESIZE];
  137.  
  138. #ifdef DEBUG
  139.     ll_log (logptr, LLOGBTR, "qu2lo_each()");
  140. #endif
  141.     /* while there are addessses to process... */
  142.     FOREVER
  143.     {
  144.         result = qu_radr (host, lo_adr);
  145.         if (rp_isbad (result))
  146.             return (result);      /* get address from Deliver */
  147.  
  148.         if (rp_gval (result) == RP_HOK)
  149.         {                       /* no-op the sub-list indication */
  150.             qu_wrply ((RP_Buf *) &rp_hend, rp_conlen (rp_hend));
  151.             continue;
  152.         }
  153.  
  154.         if (rp_gval (result) == RP_DONE)
  155.         {
  156.             qu_wrply ((RP_Buf *) &rp_aend, rp_conlen (rp_aend));
  157.             return (RP_OK);       /* end of address list */
  158.         }
  159.  
  160.         replyval.rp_val = lo_verify ();
  161.         if (rp_isbad (replyval.rp_val)) {
  162.             qu_wrply (&replyval, (sizeof replyval.rp_val));
  163.             continue;                       /* go for more! */
  164.         }
  165.  
  166.         replyval.rp_val = lo_master ();
  167.         switch (rp_gval (replyval.rp_val)) {
  168.         case RP_LIO:
  169.         case RP_TIME:
  170.             /* RP_AGN prevents deliver from calling us dead */
  171.             replyval.rp_val = RP_AGN;
  172.         case RP_LOCK:
  173.         case RP_USER:         /* typicial valid responses */
  174.         case RP_BHST:
  175.         case RP_NOOP:
  176.         case RP_NO:
  177.         case RP_MOK:
  178.         case RP_AOK:
  179.         case RP_OK:
  180.             break;
  181.         default:              /* not expected so may abort          */
  182.             if (rp_isgood (replyval.rp_val))
  183.             {
  184.                 ll_log (logptr, LLOGFAT,
  185.                 "lo_wadr = %s", rp_valstr (replyval.rp_val));
  186.                 replyval.rp_val = RP_RPLY;  /* Conservative */
  187.             }
  188.         }
  189.         qu_wrply (&replyval, (sizeof replyval.rp_val));
  190.     }
  191. }
  192.  
  193. LOCFUN
  194. lo_verify ()                    /* send one address spec to local     */
  195. {
  196.     char    mailid[MAILIDSIZ];      /* mailid of recipient */
  197.     register char   *p;
  198.     extern char     *strncpy();
  199. #ifdef DEBUG
  200.     ll_log (logptr, LLOGBTR, "lo_verify()");
  201. #endif
  202.     /* Strip any trailing host strings from address */
  203.     if (p = index (lo_adr, '@'))
  204.         *p = '\0';
  205.  
  206.     for (p = lo_adr; ; p++) {
  207.         switch (*p) {
  208.         case '|':
  209.         case '/':
  210.         case '=':
  211.         case '\0':
  212.             lo_parm = p;
  213.             strncpy (mailid, lo_adr, p - lo_adr);
  214.             mailid[p - lo_adr] = '\0';
  215.             goto checkit;
  216.         }
  217.     }
  218.  
  219. checkit:
  220.     if ((lo_pw = getpwmid (mailid)) == (struct passwd *) NULL) {
  221.         ll_err (logptr, LLOGTMP, "user '%s' unknown", mailid);
  222.         return (RP_USER);     /* can't deliver to non-persons       */
  223.     }
  224.     return (RP_OK);          /* Invalid addresss or real problems */
  225. }
  226.  
  227. LOCFUN
  228. lo_master()
  229. {
  230.     int   childid;                /* child does the real work           */
  231.  
  232.     switch (childid = fork ()) {
  233.     case NOTOK:
  234.         return (RP_LIO);        /* problem with system */
  235.  
  236.     case OK:
  237.         ll_close (logptr);      /* since the process is splitting */
  238.  
  239. #ifdef V4_2BSD
  240.         if (initgroups (lo_pw->pw_name, lo_pw->pw_gid) == NOTOK
  241.           || setgid (lo_pw->pw_gid) == NOTOK
  242. #else
  243.         if (setgid (lo_pw->pw_gid) == NOTOK
  244. #endif /* V4_2BSD */
  245.           || setuid (lo_pw->pw_uid) == NOTOK) {
  246.             ll_err (logptr, LLOGTMP, "can't set id's (%d,%d)",
  247.                 lo_pw->pw_uid, lo_pw->pw_gid);
  248.             exit (RP_BHST);
  249.         }
  250.  
  251.         if (chdir (lo_pw->pw_dir) == NOTOK) {
  252.             /* move out of MMDF queue space       */
  253.             ll_err (logptr, LLOGTMP, "can't chdir to '%s'",
  254.                 lo_pw->pw_dir);
  255.             exit (RP_LIO);
  256.         }
  257.  
  258.         exit (lo_slave());
  259.  
  260.     default:                  /* parent just waits  */
  261.         return (pgmwait (childid));
  262.     }
  263.     /* NOTREACHED */
  264. }
  265.